<!DOCTYPE html>
<html>
<head>
	<title>meteor shower</title>
	<meta charset="utf-8" />
	<style type="text/css">
		body{
		  background: #000;
		  overflow: hidden;
		}

		canvas{
		  width: 100%;
		  height: 100%;
		  position: absolute;
		  left: 0;
		  top: 0;
		}
	</style>
</head>
<body>

	<canvas id="canvas"></canvas>

	<script type="text/javascript">
		
		class Line {
		  constructor(x, y, size, color, speed, seed, amplitude) {
		    this.x = x
		    this.y = y
		    this.size = size
		    this.color = color
		    this.speed = speed
		    this.seed = seed
		    this.amplitude = amplitude
		    this.i = this.seed
		  }
		  
		  update() {
		    this.y -= this.speed
		    this.i += this.seed
		  }
		  
		  draw(canvas) {
		    const x = this.x + (Math.sin(this.i)  * this.amplitude)
		    
		    canvas.ctx.beginPath()
		    canvas.ctx.fillStyle = this.color
		    canvas.ctx.shadowColor = this.color
		    canvas.ctx.shadowBlur = 5
		    canvas.ctx.arc(x, this.y, this.size, 0, 2 * Math.PI)
		    canvas.ctx.fill()
		    canvas.ctx.closePath()
		  }
		}

		class Canvas {
		  constructor(ctx, w, h) {
		    this.ctx = ctx
		    this.width = w
		    this.height = h
		    this.scale = 1.0
		    this.lines = []
		  }
		  
		  pushParticle() {
		    const x = Math.random() * this.width
		    const y = this.height + (Math.random() * 250)
		    const size = 1 + Math.random()
		    
		    const g = Math.floor(150 + (Math.random() * 50))
		    const b = Math.floor(150 + (Math.random() * 50))
		    const color = 'rgba(120,' + g + ',' + b + ',0.7)'
		    
		    const speed = 2 + (Math.random() * 1.5)
		    const seed = Math.random() / 20
		    const amp = Math.random() * 15

		    this.lines.push(new Line(x, y, size, color, speed, seed, amp))
		  }
		  
		  start() {  
		    for (let i = 0; i < 100; i++) {
		      this.pushParticle()
		    }
		  }
		  
		  update() {
		    for (let i = 0; i < this.lines.length; i++) {
		      const line = this.lines[i]
		      
		      line.update()
		    }
		    
		    this.lines = this.lines.filter(line => {
		      return line.y > -2
		    })
		    
		    const toAdd = 100 - this.lines.length
		    
		    if (toAdd === 0) { return }
		    
		    for (let i = 0; i < toAdd; i++) {
		      this.pushParticle()
		    }
		  }
		  
		  draw() {
		    this.ctx.shadowColor = '#000'
		    this.ctx.shadowBlur = 0
		    this.ctx.globalCompositeOperation = 'source-over'
		    this.ctx.fillStyle = 'rgba(0, 0, 0, 0.05)'
		    this.ctx.fillRect(0, 0, this.width, this.height)
		    this.ctx.globalCompositeOperation = 'lighter'
		    
		    for (let i = 0; i < this.lines.length; i++) {
		      const line = this.lines[i]
		      
		      line.draw(this)
		    }
		  }
		}

		(_ => {
		  const canvasElement = document.getElementById('canvas'),
		        ctx = canvasElement.getContext('2d'),
		        canvas = new Canvas(ctx)
		  
		  let w = canvasElement.width = window.innerWidth,
		      h = canvasElement.height = window.innerHeight,
		      density = 1
		  
		  function setup() {
		    window.addEventListener('resize', resize)
		    
		    density = window.devicePixelRatio != undefined ? window.devicePixelRatio : 1.0
		    
		    canvasElement.width = w * density
				canvasElement.height = h * density
				
		    canvas.width = w
		    canvas.height = h
		    canvas.scale = density
		    
				ctx.scale(density,density)
		    
		    canvas.start()
		    
		    draw()
		  }
		  
		  function draw() {
		    canvas.update()
		    canvas.draw()
		    
		    window.requestAnimationFrame(draw)
		  }
		  
		  function resize() {
		    w = canvasElement.width = window.innerWidth
		    h = canvasElement.height = window.innerHeight
		    
		    canvasElement.width = w * density
				canvasElement.height = h * density
		    
		    canvas.width = w
		    canvas.height = h
		    
		    ctx.scale(density, density)
		  }
		  
		  setup()
		})()
	</script>

</body>
</html>